#include "adc_task.h"
#include <rtthread.h>
#include <rtdevice.h>

/* DMA 缓冲区定义 */
#define DMA_BUFFER_SIZE 1024
static rt_uint16_t adc1_dma_buffer[DMA_BUFFER_SIZE];
static rt_uint16_t adc2_dma_buffer[DMA_BUFFER_SIZE];

/* ADC 通道配置 */
static rt_uint8_t adc1_channels[] = {4, 5, 6};  // PA4, PA5, PA6
static rt_uint8_t adc2_channels[] = {9};         // PF3

/* ADC 设备信息 */
static app_adc_device_t adc1_info = {
    .name = "adc1",
    .channel_count = 3,
    .channels = adc1_channels,
    .dma_buffer = adc1_dma_buffer,
    .dma_buffer_size = DMA_BUFFER_SIZE
};

static app_adc_device_t adc2_info = {
    .name = "adc2", 
    .channel_count = 1,
    .channels = adc2_channels,
    .dma_buffer = adc2_dma_buffer,
    .dma_buffer_size = DMA_BUFFER_SIZE
};

/* 引脚重映射配置（PF3） */
static void adc_pin_remap_config(void)
{
    /* 启用相关时钟 */
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_SYSCFG);
    rcu_periph_clock_enable(RCU_DMA1);
    
    /* 配置 PF3 为模拟输入 */
    gpio_mode_set(GPIOF, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);    
}

int app_adc_init(void)
{
    rt_err_t ret;
    
    /* 配置引脚重映射 */
    adc_pin_remap_config();
    
    /* 初始化 ADC1 */
    adc1_info.dev = (rt_adc_device_t)rt_device_find("adc1");
    if (adc1_info.dev == RT_NULL)
    {
        rt_kprintf("ADC1 device not found!\n");
        return -RT_ERROR;
    }
    
    /* 设置 ADC1 DMA 缓冲区 */
    struct rt_adc_dma_config dma_config1 = {
        .buffer = adc1_dma_buffer,
        .size = DMA_BUFFER_SIZE
    };
    rt_adc_control(adc1_info.dev, RT_ADC_CMD_SET_DMA_BUFFER, &dma_config1);
    
    /* 启用 ADC1 通道 */
    for (int i = 0; i < adc1_info.channel_count; i++)
    {
        ret = rt_adc_enable(adc1_info.dev, adc1_info.channels[i]);
        if (ret != RT_EOK)
        {
            rt_kprintf("Enable ADC1 channel %d failed!\n", adc1_info.channels[i]);
        }
    }
    
    /* 初始化 ADC2 */
    adc2_info.dev = (rt_adc_device_t)rt_device_find("adc2");
    if (adc2_info.dev == RT_NULL)
    {
        rt_kprintf("ADC2 device not found!\n");
        return -RT_ERROR;
    }
    
    /* 设置 ADC2 DMA 缓冲区 */
    struct rt_adc_dma_config dma_config2 = {
        .buffer = adc2_dma_buffer,
        .size = DMA_BUFFER_SIZE
    };
    rt_adc_control(adc2_info.dev, RT_ADC_CMD_SET_DMA_BUFFER, &dma_config2);
    
    /* 启用 ADC2 通道 */
    ret = rt_adc_enable(adc2_info.dev, adc2_info.channels[0]);
    if (ret != RT_EOK)
    {
        rt_kprintf("Enable ADC2 channel %d failed!\n", adc2_info.channels[0]);
    }
    
    rt_kprintf("ADC initialization completed!\n");
    return RT_EOK;
}

void app_adc_start(void)
{
    if (adc1_info.dev) rt_adc_control(adc1_info.dev, RT_ADC_CMD_START, RT_NULL);
    if (adc2_info.dev) rt_adc_control(adc2_info.dev, RT_ADC_CMD_START, RT_NULL);
}

void app_adc_stop(void)
{
    if (adc1_info.dev) rt_adc_control(adc1_info.dev, RT_ADC_CMD_STOP, RT_NULL);
    if (adc2_info.dev) rt_adc_control(adc2_info.dev, RT_ADC_CMD_STOP, RT_NULL);
}

rt_uint16_t app_adc_get_value(rt_uint8_t adc_index, rt_uint8_t channel_index)
{
    app_adc_device_t *adc_info;
    
    if (adc_index == 1)
        adc_info = &adc1_info;
    else if (adc_index == 2)
        adc_info = &adc2_info;
    else
        return 0;
    
    if (channel_index >= adc_info->channel_count)
        return 0;
    
    /* 从 DMA 缓冲区读取数据 */
    /* DMA缓冲区索引计算 */
    /* 在多通道扫描模式下，数据是按 [ch0, ch1, ch2, ch0, ch1, ch2...] 顺序存储的 */ 
    /* 所以需要计算当前最新数据的位置 */
    
    rt_uint32_t idx = (adc_info->dma_buffer_size - (adc_info->channel_count * 10)) + channel_index;
    return adc_info->dma_buffer[idx];
}

app_adc_device_t *app_get_adc1_info(void) { return &adc1_info; }
app_adc_device_t *app_get_adc2_info(void) { return &adc2_info; }

/* 线程栈大小 */
#define ADC_THREAD_STACK_SIZE 2048

/* 线程优先级和时间片 */
#define ADC_THREAD_PRIORITY   20
#define ADC_THREAD_TIMESLICE  10

/* 线程控制块（静态分配，避免动态内存占用） */
static struct rt_thread adc_thread;

/* 线程栈（静态分配） */
static rt_uint8_t adc_thread_stack[ADC_THREAD_STACK_SIZE];

/* 线程入口函数 */
static void adc_thread_entry(void *parameter)
{
    /* 初始化 ADC */
    if (app_adc_init() != RT_EOK)
    {
        rt_kprintf("ADC init failed!\n");
        return;
    }
    
    /* 启动 ADC 转换 */
    app_adc_start();

    /* 待DMA开始传输 */
    rt_thread_mdelay(100);

    while (1)
    {
        rt_uint16_t v = ADC_RDATA(ADC1);
        rt_kprintf("ADC1_RDATA=%04X\n", v);
        
        /* 读取 ADC1 数据 */
        rt_uint16_t adc1_ch4 = app_adc_get_value(1, 0); // PA4
        rt_uint16_t adc1_ch5 = app_adc_get_value(1, 1); // PA5  
        rt_uint16_t adc1_ch6 = app_adc_get_value(1, 2); // PA6
        
        /* 读取 ADC2 数据 */
        rt_uint16_t adc2_ch9 = app_adc_get_value(2, 0); // PF3
        
        rt_kprintf("ADC1: CH4=%d, CH5=%d, CH6=%d | ADC2: CH9=%d\n",
                  adc1_ch4, adc1_ch5, adc1_ch6, adc2_ch9);
        
        rt_thread_mdelay(100);
        rt_kprintf("DMA1_CH2 CNTR=%d\n",
        DMA_CHCNT(DMA1, DMA_CH2));
        rt_kprintf("ADC1_CTL1 SWRCST bit = %08x\n", ADC_CTL1(ADC1) & ADC_CTL1_SWRCST);
        rt_kprintf("ADC1_CTL1 = %08x\n", ADC_CTL1(ADC1));
    }
}

/* 任务初始化函数（封装线程创建与启动逻辑） */
rt_err_t adc_task_init(void)
{
    rt_err_t result = RT_EOK;

    /* 初始化线程 */
    result = rt_thread_init(&adc_thread,
                           "adc_sample",
                           adc_thread_entry,
                           RT_NULL,
                           &adc_thread_stack[0],
                           ADC_THREAD_STACK_SIZE,
                           ADC_THREAD_PRIORITY,
                           ADC_THREAD_TIMESLICE);

    if (result == RT_EOK)
    {
        /* 启动线程 */
        rt_thread_startup(&adc_thread);
        rt_kprintf("ADC task started successfully!\n");
    }
    else
    {
        rt_kprintf("Failed to init ADC task: %d\n", result);
    }

    return result;
}